'''
1. 获取页面源代码
    1. 找到未加密的参数
    2. 使用python 模拟网易云的加密逻辑 params => encText ,  encSecKey => encSecKey
    3. 获取评论区数据
2. 将每一条数据保存到文件中
'''
import csv
import json
import requests
from Crypto.Cipher import AES
from base64 import b64encode

# 参数
# 数据参数
data = {
    "csrf_token": "",
    "cursor": "-1",
    "offset": "0",
    "orderType": "1",
    "pageNo": "1",
    "pageSize": "20",
    "rid": "R_SO_4_2672492276",
    "threadId": "R_SO_4_2672492276"
}

e = '010001'
f = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
g = '0CoJUm6Qyw8W8jud'

# 固定随机数
i = "S6uYx1a9vkddGnC7"

# 获取encSecKey
def get_encSecKey():
    return "c832f0705158e5b71b4ecfb2b90013d6704d82fba11d87a8ad53e2bc687d22df64c7c0210895e5ece1e85fff507cbbc98e5ad67880b324634536c235e7e575d3f5806e38dd5502460d1818b32ca9ce7af3a1714cfc17914ab83d1373055e94a1820cd6913c3dc7576ab8c495339a334ec07c4a14b783a900f1cb2fae1065e122"

# 获取params
def get_params(data):  # 默认data 为字符串
    first = enc_params(data, g)
    second = enc_params(first, i)
    return second  # 返回params

def to_16(data):
    pad = 16 - len(data) % 16
    data += chr(pad) * pad
    return data

# 加密过程
def enc_params(data, key):
    iv = "0102030405060708"
    data = to_16(data)
    aes = AES.new(key=key.encode("utf-8"), IV=iv.encode("utf-8"), mode=AES.MODE_CBC)  # 创建加密器
    bs = aes.encrypt(data.encode("utf-8"))  # 加密, 加密的内容的长度必须是16 的倍数f
    return str(b64encode(bs), "utf-8")  # 转换成字符串返回


# 分析处理加密过程
'''
    function a(a = 16) {  # 返回随机的16 位字符串
        var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
        for (d = 0; a = 16 > d; d += 1)  # 循环16 次
            e = Math.random() * b.length,  # 随机数 例: 1.234
            e = Math.floor(e),  # 取整 例: 1
            c += b.charAt(e);  # 取字符串中的xxx位置 例: b
        return c
    }
    function b(a, b) {  # a 是要加密的内容
        var c = CryptoJS.enc.Utf8.parse(b)  # b 是密钥
          , d = CryptoJS.enc.Utf8.parse("0102030405060708")
          , e = CryptoJS.enc.Utf8.parse(a)  # e 是数据
          , f = CryptoJS.AES.encrypt(e, c, {  # c 是加密的密钥
            iv: d,  # 偏移量  AES 加密算法中的iv
            mode: CryptoJS.mode.CBC  # 模式: CBC
        });
        return f.toString()
    }
    function c(a, b, c) {
        var d, e;
        return setMaxDigits(131),
        d = new RSAKeyPair(b,"",c),
        e = encryptedString(d, a)
    }
    function d(d, e, f, g) {  d: data  e: 010001  f: 固定很长  g: 固定字符串 
        var h = {}  # 空对象
          , i = a(16);  # i 是 16 位随机值  若把i 设置成固定值, encSecKey 也是固定的
        h.encText = b(d, g)  # 参数: d 数据  g 固定字符串 (密钥)
        h.encText = b(h.encText, i)  # 返回 params 参数: 第一次加密 i 第二次加密的密钥
        h.encSecKey = c(i, e, f)  # 返回 encSecKey  e 和 f 固定 
        return h
    }
    
    两次加密: 
    数据 + g: 固定 = 第一次加密
    第一次加密 + i: 已设置固定 = 第二次加密
'''

# 发送请求
url = "https://music.163.com/weapi/comment/resource/comments/get?csrf_token="
head = {
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36"
}

resp = requests.post(url, headers=head, data={
    "params": get_params(json.dumps(data)),
    "encSecKey": get_encSecKey()
})

# 获得数据
all_data = resp.json()["data"]

# 获得所有评论 (首页)
comments = all_data["comments"]

# 获得热门评论 (首页)
hotComments = all_data["hotComments"]

# 存入文件中
f = open("comment.csv", mode="w", encoding="utf-8")
csv_writer = csv.writer(f)

newComment = "最新评论~~~"
niceComment = "精彩评论~~~"
commentName = "评论"
repliesName = "留言"

# 遍历评论
csv_writer.writerow(newComment.split(","))
for comment in comments:
    # 评论
    nickname = comment["user"]["nickname"]
    location = comment["ipLocation"]['location']
    content = comment["content"]
    csv_writer.writerow(commentName.split(","))
    csv_writer.writerow([nickname, location, content])

    # 留言
    beReplied = comment["beReplied"]
    if beReplied is not None:
        for be in beReplied:
            nickname = be["user"]["nickname"]
            location = be["ipLocation"]["location"]
            content = be["content"]
            csv_writer.writerow(repliesName.split(","))
            csv_writer.writerow([nickname, location, content])


csv_writer.writerow(niceComment.split(","))
for hotComment in hotComments:
    # 评论
    nickname = hotComment["user"]["nickname"]
    location = hotComment["ipLocation"]['location']
    content = hotComment["content"]
    csv_writer.writerow(commentName.split(","))
    csv_writer.writerow([nickname, location, content])

    # 留言
    beReplied = hotComment["beReplied"]
    if beReplied is not None:
        for be in beReplied:
            nickname = be["user"]["nickname"]
            location = be["ipLocation"]["location"]
            content = be["content"]
            csv_writer.writerow(repliesName.split(","))
            csv_writer.writerow([nickname, location, content])



f.close()
resp.close()
print("over!")